home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #2
/
Monster Media No. 2 (Monster Media)(1994).ISO
/
prog_gen
/
gcoope10.zip
/
STREAM.C
< prev
next >
Wrap
Text File
|
1994-07-23
|
11KB
|
556 lines
/*
Stream object class definition for GCOOPE 1.0
This class is for stream interface to user defined i/o objects
released as PUBLIC DOMAIN 4/25/94 ported to GCOOPE 7/21/94
A user defined i/o object is one that includes methods for
the generics described in the LowStream class definition.
(May, of course, be an inheritor of LowStream).
*/
#define CLASS Stream
#include "gcoope10.h"
#include "stream.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
object CLASS;
extern object String;
typedef struct {
object ioObj;
unsigned char * buffer;
unsigned char hold;
short int bsize;
short int curPos;
unsigned flags;
} instVars;
USEGEN(getPos);
USEGEN(setPos);
USEGEN(strmErr);
USEGEN(putByte);
USEGEN(getByte);
USEGEN(Putc);
USEGEN(Getc);
USEGEN(UnGet);
USEGEN(Puts);
USEGEN(Gets);
USEGEN(Write);
USEGEN(Read);
USEGEN(SetBuf);
USEGEN(Flush);
USEGEN(clrErr);
USEGEN(Stat);
USEGEN(asString);
USEGEN(addressOf);
cmethod object m4New(object instance, object ioObj, const char * mode)
{
instVars * ivptr;
if(NULL==(ivptr=makeInst(&instance))) return 0L;
ivptr->ioObj=ioObj;
ivptr->flags=S_BIN;
ivptr->buffer=NULL;
if(NULL!=strchr(mode,'r')) ivptr->flags |= S_READ;
if(NULL!=strchr(mode,'w')) ivptr->flags |= S_WRITE;
if(NULL!=strchr(mode,'t')) ivptr->flags &= ~S_BIN;
if(NULL!=strchr(mode,'+')) ivptr->flags |= S_RDWR;
return instance;
}
imethod object m4SetBuf(object instance,char * buffer,
int type, word size)
{
instVars * ivptr;
if(NULL==(ivptr=getIVptr(instance))) return FUNCFAIL;
if(ivptr->buffer != NULL || size<=0) return FUNCFAIL;
if(type==_IONBF) return FUNCFAIL;
ivptr->buffer=(unsigned char *)buffer;
ivptr->bsize=size;
ivptr->flags|=S_BUF;
if(type==_IOLBF) ivptr->flags|=S_LBUF;
return FUNCOKAY;
}
imethod object m4Flush(object instance)
{
object (*wrDest)(object,char);
unsigned char * ptrA;
instVars * ivptr;
if(NULL==(ivptr=getIVptr(instance))) return FUNCFAIL;
if(ivptr->flags & S_WRITE && ivptr->curPos>0)
{
(method) wrDest=g(GEN(putByte), ivptr->ioObj);
for(ptrA=ivptr->buffer;ivptr->curPos>0;ivptr->curPos--,ptrA++)
{
if(wrDest(ivptr->ioObj,*ptrA))
{
ivptr->flags |= S_EOS;
return FUNCFAIL;
}
}
}
else ivptr->curPos=0;
ivptr->hold=0;
return FUNCOKAY;
}
static int fillBuff(object instance)
{
int x;
int (*rdSrc)(object);
instVars * ivptr;
if(NULL==(ivptr=getIVptr(instance))) return EOF;
(method) rdSrc=g(GEN(getByte), ivptr->ioObj);
for(ivptr->curPos=0;ivptr->curPos<ivptr->bsize;ivptr->curPos++)
{
if(EOF==(x=rdSrc(ivptr->ioObj))) return x;
(unsigned char)ivptr->buffer[ivptr->curPos++]=x;
}
ivptr->curPos=0;
return x;
}
imethod long m4getPos(object instance)
{
long rv;
instVars * ivptr;
if(NULL==(ivptr=getIVptr(instance)) || m4Flush(instance))
{
rv = -1;
}
else
{
rv=g(GEN(getPos))(ivptr->ioObj);
if(rv<0) ivptr->flags |= S_ERR;
}
return rv;
}
imethod object m4setPos(object instance, long newPos, int whence)
{
object rv=FUNCFAIL;
instVars * ivptr;
if(NULL!=(ivptr=getIVptr(instance)) &&
FUNCOKAY==(rv=m4Flush(instance)))
{
if(newPos==0) ivptr->flags &= (S_RDWR | S_BUF | S_LBUF | S_BIN);
else ivptr->flags &= (S_RDWR | S_BUF | S_LBUF | S_BIN | S_ERR);
if(FUNCFAIL==(rv= g(GEN(setPos))(ivptr->ioObj, newPos, whence)))
ivptr->flags|=S_EOS;
}
else ivptr->flags |= S_ERR;
return rv;
}
imethod object m4clrErr(object instance)
{
instVars * ivptr;
if(NULL==(ivptr=getIVptr(instance)) || g(GEN(clrErr))(ivptr->ioObj))
return FUNCFAIL;
ivptr->flags&=(S_RDWR | S_BUF | S_LBUF | S_BIN);
return FUNCOKAY;
}
imethod object m4Stat(object instance)
{
return (object) ((instVars *) getIVptr(instance))->flags;
}
imethod int m4Putc(object instance, char c)
{
int rv=EOF;
instVars * ivptr;
if(NULL==(ivptr=getIVptr(instance))) goto done;
if(OKAY_W)
{
if(c=='\n' && !(ivptr->flags & S_BIN))
{
m4Putc(instance,'\r');
}
SET_W;
if(ivptr->flags & S_BUF)
{
if(ivptr->curPos>=ivptr->bsize)
{
if(m4Flush(instance)) goto done;
}
rv=((unsigned char)ivptr->buffer[ivptr->curPos++]=c);
if(c=='\n' && ivptr->flags&S_LBUF)
{
m4Flush(instance);
}
}
else rv=(g(GEN(putByte))(ivptr->ioObj, c))?EOF:c;
if(rv==EOF) ivptr->flags|=S_EOS;
}
else ivptr->flags|=S_ERR;
done:
return rv;
}
imethod int m4Getc(object instance)
{
int rv=EOF;
instVars * ivptr;
if(NULL==(ivptr=getIVptr(instance))) return rv;
restart:
rv=EOF;
if(OKAY_R)
{
if(ivptr->flags & S_BUF)
{
if(!(ivptr->flags & S_IN) || ivptr->curPos>=ivptr->bsize)
{
SET_R;
if(EOF==(rv=fillBuff(instance))) goto done;
}
rv=((unsigned char)ivptr->buffer[ivptr->curPos++]);
}
else
{
SET_R;
if(ivptr->hold!=0)
{
rv=ivptr->hold;
ivptr->hold=0;
}
else rv=((INTRV)g)(GEN(getByte))(ivptr->ioObj);
}
if(rv==EOF) ivptr->flags |= S_EOS;
}
else ivptr->flags |= S_ERR;
done:
if((unsigned char)rv=='\r' && !(ivptr->flags&S_BIN))goto restart;
return rv;
}
imethod int m4UnGet(object instance, char c)
{
int rv=EOF;
instVars * ivptr;
if(NULL==(ivptr=getIVptr(instance))) return rv;
if(OKAY_R && ivptr->flags & S_IN)
{
if(ivptr->flags&=S_BUF)
{
if(ivptr->curPos>0)
rv=((unsigned char)ivptr->buffer[--ivptr->curPos]=c);
}
else rv=((unsigned char)ivptr->hold=c);
}
if(rv==EOF) ivptr->flags|=S_ERR;
return rv;
}
imethod object m4Puts(object instance, object dataObj)
{
char * s;
int rv=EOF;
int x=0;
method direct;
instVars * ivptr;
dataObj=g(GEN(asString))(dataObj);
s=((VDPTRRV)g)(GEN(addressOf))(dataObj);
if(NULL==(ivptr=getIVptr(instance))) return FUNCFAIL;
if(OKAY_W && s!=NULL)
{
SET_W;
if(ivptr->flags & S_BUF)
{
while(s[x]!=0)
{
if(s[x]=='\n' && !(ivptr->flags&S_BIN))
{
rv=m4Putc(instance,'\r');
}
if(ivptr->curPos>=ivptr->bsize)
{
if(m4Flush(instance))
{
rv=EOF;
break;
}
}
rv=((unsigned char)ivptr->buffer[ivptr->curPos++]=s[x]);
if(s[x]=='\n' && ivptr->flags&S_LBUF && ivptr->curPos>0)
{
if(m4Flush(instance))
{
rv=EOF;
break;
}
}
x++;
}
}
else
{
direct=g(GEN(putByte), ivptr->ioObj);
while(s[x]!=0)
{
if(s[x]=='\n' && !(ivptr->flags&S_BIN))
{
rv=(direct(ivptr->ioObj,'\r'))?EOF:'\r';
if(rv==EOF) break;
}
rv=s[x++];
rv=(direct(ivptr->ioObj,(char) rv))?EOF:rv;
if(rv==EOF) break;
}
}
if(rv==EOF) ivptr->flags |= S_EOS;
}
else ivptr->flags |= S_ERR;
return (rv==EOF)?FUNCFAIL:FUNCOKAY;
}
imethod object m4Gets(object instance, int max)
{
int x=0;
int rv=EOF;
int (*direct)(object);
instVars * ivptr;
char * d;
object newStr;
if(NULL==(ivptr=getIVptr(instance))) return (object) NULL;
d=s_malloc(max);
if(OKAY_R && d!=NULL)
{
if(ivptr->flags & S_BUF)
{
rv=0;
if(!(ivptr->flags & S_IN) || ivptr->curPos>=ivptr->bsize)
{
SET_R;
if(EOF==(rv=fillBuff(instance))) x=max;
}
while(x<max-1)
{
d[x]=(unsigned char)ivptr->buffer[ivptr->curPos++];
if(ivptr->curPos>=ivptr->bsize &&
EOF==(rv=fillBuff(instance))) break;
if(d[x]=='\r' && !(ivptr->flags&S_BIN)) continue;
if(d[x++]=='\n') break;
}
d[x]=0;
}
else
{
SET_R;
(method) direct = g(GEN(getByte),ivptr->ioObj);
while(x<max-1)
{
if(EOF==(rv=direct(ivptr->ioObj)))
break;
if((d[x]=(unsigned char) rv)=='\r'
&& !(ivptr->flags&S_BIN)) continue;
if(d[x++]=='\n') break;
}
d[x]=0;
}
if(rv==EOF)
{
ivptr->flags|=S_EOS;
return (object) NULL;
}
newStr=g(New)(String,d);
s_free(d);
return newStr;
}
ivptr->flags|=S_ERR;
return (object) NULL;
}
imethod int m4Write(object instance, const char * ptr, word size,
word n)
{
method direct;
word x,max;
int rv=0;
instVars * ivptr;
if(NULL==(ivptr=getIVptr(instance))) return EOF;
if(OKAY_W && ptr != NULL && size > 0 && n > 0)
{
SET_W;
if(ivptr->flags & S_BUF)
{
for(x=0,max=size*n;x<max;x++)
{
if(ptr[x]=='\n' && !(ivptr->flags&S_BIN))
{
m4Putc(instance,'\r');
}
if(ivptr->curPos>=ivptr->bsize)
{
if(m4Flush(instance))
{
rv=EOF;
break;
}
}
(unsigned char)ivptr->buffer[ivptr->curPos++]=ptr[x];
if(ptr[x]=='\n' && ivptr->flags&S_LBUF && ivptr->curPos>0)
{
if(m4Flush(instance))
{
rv=EOF;
break;
}
}
}
}
else
{
direct=g(GEN(putByte),ivptr->ioObj);
for(x=0,max=size*n;x<max;x++)
{
if(ptr[x]=='\n' && !(ivptr->flags&S_BIN))
{
if(direct(ivptr->ioObj,'\r'))
{
rv=EOF;
break;
}
}
if(direct(ivptr->ioObj,ptr[x]))
{
rv=EOF;
break;
}
}
}
if(EOF==rv)
{
ivptr->flags|=S_EOS;
}
else
{
rv=(max>x)?x:max;
}
}
else
{
ivptr->flags|=S_ERR;
}
return rv;
}
imethod int m4Read(object instance, char * ptr, word size, word n)
{
word x,max;
int (*direct)(object);
int rv=0;
instVars * ivptr;
if(NULL==(ivptr=getIVptr(instance))) return EOF;
if(OKAY_R && ptr != NULL && size > 0 && n > 0)
{
if(ivptr->flags & S_BUF)
{
if(!(ivptr->flags & S_IN) || ivptr->curPos>=ivptr->bsize)
{
SET_R;
if(EOF==(rv=fillBuff(instance))) size=0;
}
for(x=0,max=size*n;x<max;x++)
{
ptr[x]=(unsigned char)ivptr->buffer[ivptr->curPos++];
if(ivptr->curPos>=ivptr->bsize)
if(EOF==(rv=fillBuff(instance))) break;
if(ptr[x]=='\r' && !(ivptr->flags&S_BIN))
{
x--;
continue;
}
}
}
else
{
SET_R;
(method) direct = g(GEN(getByte), ivptr->ioObj);
for(x=0,max=size*n;x<max;x++)
{
if(EOF==(rv=direct(ivptr->ioObj)))
break;
if((ptr[x]=(unsigned char) rv)=='\r'
&& !(ivptr->flags&S_BIN))
{
x--;
continue;
}
}
}
if(rv==EOF)
{
ivptr->flags|=S_EOS;
}
else
{
rv=(x<max)?x:max;
}
}
else ivptr->flags|=S_ERR;
return rv;
}
CLASS_INSTALL
{
if(END==(CLASS=g(New)(Class, 0, sizeof(instVars), END))
|| addGMthd(CLASS, New, (method) m4New)
|| ADDGM(getPos) || ADDGM(setPos) || ADDGM(Putc) || ADDGM(Getc)
|| ADDGM(Getc) || ADDGM(UnGet) || ADDGM(Puts) || ADDGM(Gets)
|| ADDGM(Write) || ADDGM(Read) || ADDGM(SetBuf) || ADDGM(Flush)
|| ADDGM(clrErr) || ADDGM(Stat)) return FUNCFAIL;
else return FUNCOKAY;
}